/**
 * @file cTestFlash.c
 * @brief 
 * @author xuesong (wenshaoliu@foxmail.com)
 * @version 1.0
 * @date 2024-11-25
 * 
 * @copyright Copyright (c) 2024  by xuesong
 * 
 * @par 修改日志:
 * <table>
 * <tr><th>Date       <th>Version <th>Author  <th>Description
 * <tr><td>2024-11-25     <td>1.0     <td>xuesong   <td>内容
 * </table>
 */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include "fal_cfg.h"
#include "fal_def.h"
#include "UseFlash.h"

#define FLASH_FILE  "G:/Tools/flash/CmakeFlashDB/demos/cmakeVer/flashDB/port/FlashMem.bin"
// #define FLASH_FILE  "FlashMem.bin"

int flash_read_page(unsigned long addr, unsigned long len, unsigned char *buf)
{
    int retValue = 0;
    FILE *readFlashFp = fopen(FLASH_FILE, "rb");
  //如果文件打开失败，打印错误码和错误描述
    if (readFlashFp == NULL) {
        int errorCode = errno;
        char* errorMsg = strerror(errorCode);
        printf("Open file fail, errorCode:%d, errorMsg:%s\n", errorCode, errorMsg);
        return -1;
    }
    fseek(readFlashFp, addr, SEEK_SET); // 重置文件指针到读取起始位置
    retValue = fread(buf, 1, len, readFlashFp);
    fclose(readFlashFp);
    return retValue;
}
int flash_write_page(unsigned long addr, unsigned long len, unsigned char *buf)
{
    int retValue = 0;
    FILE *WriteFlashFp = fopen(FLASH_FILE, "rb+");
  //如果文件打开失败，打印错误码和错误描述
    if (WriteFlashFp == NULL) {
        int errorCode = errno;
        char* errorMsg = strerror(errorCode);
        printf("Open file fail, errorCode:%d, errorMsg:%s\n", errorCode, errorMsg);
        return -1;
    }
    fseek(WriteFlashFp, addr, SEEK_SET); // 重置文件指针到读取起始位置
    retValue = fwrite(buf, 1, len, WriteFlashFp);
    fclose(WriteFlashFp);
    return retValue;
}

void flash_erase_sector(unsigned long addr)
{
    log_d("flash erase sector = %08X\r\n", addr);
    if ((addr % PAGE_SIZE) != 0)
    {
        log_d("flash erase sector addr err = %08X\r\n", addr);
        return;
    }
    uint16_t addrOffset = 0;
    uint8_t dataBuf[256] = {0xFF};
    memset(dataBuf, 0xFF, 256);
    for (; addrOffset < PAGE_SIZE; addrOffset+=256)
    {
        flash_write_page(addr + addrOffset, 256, dataBuf);
    }
}


void fullTestFlashBin(void)
{
    uint32_t binNeedMaxByte = EF_START_ADDR + ENV_AREA_SIZE + TSDB1_AREA_SIZE + LOG_AREA_SIZE;
    uint32_t fileLen = 0;
    FILE *readFlashFp = fopen(FLASH_FILE, "rb+");
    if(readFlashFp == NULL)
    {
        log_d("read file err,new file\r\n");
        readFlashFp = fopen(FLASH_FILE, "wb");
        for(uint32_t wIndex = 0; wIndex < binNeedMaxByte;)
        {
            flash_erase_sector(wIndex);
            wIndex += PAGE_SIZE;
        }
    }
    else{
        if(fseek(readFlashFp,0,SEEK_END) != 0){                 //移动文件指针到文件尾
            log_d("fseek failed: %s\r\n",strerror(errno));
            return -1;
        }
        fileLen = ftell(readFlashFp);                           //获取此时偏移值，即文件大小
        if(fileLen == -1){
            printf("ftell failed :%s\n", strerror(errno));
        }
        fclose(readFlashFp);

        if(fileLen < binNeedMaxByte)
        {
            uint8_t *Buff = malloc(binNeedMaxByte-fileLen);
            memset(Buff,0xFF,binNeedMaxByte-fileLen);
            flash_write_page(fileLen,binNeedMaxByte-fileLen,Buff);
            free(Buff);
        }
    }
}


